<?php

namespace app\infrastructure\base;

use app\infrastructure\enum\ResponseCode;
use app\infrastructure\helper\ResponseHelper;
use app\middleware\ParamValidate;
use think\facade\Cache;

class BaseApi extends Api
{
	protected $middleware = [
		ParamValidate::class
	];

    protected $data = [];
    protected $userId = 0;
    protected $userData = [];
    protected $httpUrl = '';

	/**
	 * 验证后数据赋值
	 * @return void
	 */
    protected function getData(): array
    {
		$this->data = $this->request->data;
		// 是否保存记录参数信息
		if (env('app_debug') && !empty($this->data)) {
			$this->consoleLog($this->data);
		}
		return $this->data;
    }

	/**
	 * 验证请求收费频繁
	 * @param int $userId
	 * @param int $timeout
	 *
	 * @return bool
	 */
    protected function verifyRequest(int $userId = 0, int $timeout = 5): bool
    {
        if (!$userId) {
            $userId = $this->userId;
        }
        $limit_key = 'limit_request_' . $userId;
        $ip = getClientIp();
        $limit_ip_key = 'limit_ip_' . $ip;
        $limit_account_key = 'limit_account_' . $userId;
        $limit = Cache::get($limit_key);
        $limit_ip = Cache::get($limit_ip_key);
        $limit_account = Cache::get($limit_account_key);
        if ($limit_account > 10) {
			return ResponseHelper::setError('操作频繁，请稍后再试');
        }
        if ($limit_account) {
            Cache::set($limit_account_key, $limit_account + 1, $timeout);
        } else {
            Cache::set($limit_account_key, 1, $timeout);
        }
        if ($limit) {
			return ResponseHelper::setError('操作频繁，请稍后再试');
        } else {
            Cache::set($limit_key, $ip, $timeout);
        }
        if ($limit_ip) {
			return ResponseHelper::setError('操作频繁，请稍后再试');
        } else {
            Cache::set($limit_ip_key, $userId, $timeout);
        }
		return true;
    }

	/**
	 * 验证用户token
	 * @param bool $require
	 *
	 * @return void
	 */
    public function verifyToken(bool $require = true): bool
    {
        $token = request()->header('Authorization');
        if (empty($token)) {
            if ($require) {
				return ResponseHelper::setError('缺少请求头Authorization');
            }
        }
        $user_token = new UserToken();
        // 特殊验证机制
        if (strpos($token, $user_token::APP_AUTH) !== false) {
            $user_id = $user_token->appAuthSha($token);
        } else {
            $user_id = $user_token->tokenAuth($token);
        }
        if (empty($user_id)) {
            if ($require) {
				return ResponseHelper::setError('系统检测到您长时间未登陆，请重新登录');
            }
        } else {
            // 获取用户信息
            $user_fields = 'user_id,mobile,user_name';
            $user_model = new User();
            $user_data = $user_model->getFind($user_id, $user_fields);
            if (empty($user_data)) {
                if ($require) {
					return ResponseHelper::setError('系统检测到您长时间未登陆，请重新登录');
                }
            } else {
                $this->data['user_id'] = $user_data['user_id'];
                $this->userId = $user_data['user_id'];
                $this->userData = $user_data;
            }
        }
		return true;
    }

    public function verifySign()
    {
        /*if (cache($this->data['sign'])){
            $this->jsonError('请勿重复操作');
        }*/
        // 验证数据信息
        /*if (!AuthService::verifySign($this->data)) {
            $this->jsonFail(AuthService::getError());
        }*/
        // 验证通过缓存sign防止重复请求
        // cache($this->data['sign'], 1, 30);
    }

    /**
     * 请求验证失败
     */
    protected function jsonFail(string $message = '')
    {
        return $this->error($message, null, ResponseCode::PARAM_ERR);
    }

    /**
     * 操作数据成功
     */
    protected function jsonSuccess(string $message = '', $data = null)
    {
        return $this->success($message, $data, ResponseCode::SUCCESS);
    }

    /**
     * 操作数据失败
     */
    protected function jsonError(string $message = '', $data = null)
    {
        empty($message) && $message = ResponseHelper::getError();
        return $this->success($message, $data, ResponseCode::ERROR);
    }

    /**
     * 获取数据成功；肯定有数据返回对象数组形式
     */
    protected function jsonResult(array $data = [], string $message = '')
    {
        return $this->success($message, $data, ResponseCode::SUCCESS);
    }

    /**
     * 没有更多数据
     */
    protected function jsonEmpty(string $message = '')
    {
        return $this->success($message, [], ResponseCode::SUCCESS);
    }

    /**
     * TOKEN失效
     */
    protected function jsonTokenFailed(string $message = '')
    {
        return $this->error($message, null, ResponseCode::UNAUTH);
    }

    /**
     * 数据日志保存
     *
     * @param     $data
     * @param     $type
     * @param int $flags
     */
    protected function consoleLog($data, $type = '', $flags = FILE_APPEND)
    {
        $dir = getcwd() . '/api_log/';
        if (!is_dir($dir)) {
            mkdir($dir, 0755, true);
        }
        $html = '';
        $filename = $dir . $type . date('YmdH') . '.html';
        if (!file_exists($filename)) {
            $html .= '<!DOCTYPE html><html><head>';
            $html .= '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';
            $html .= '</head><body>';
        }
        $html .= '<div style="display: inline-block;margin-left: 35%">';
        $html .= '<h5 style="margin: 5px 0">---------------------------------------------------------------</h5>';
        $html .= '<h5 style="margin: 5px 0">执行日期：' . date(
                'Y-m-d H:i:s',
                time()
            ) . '</h5>';
        $html .= '<h5 style="margin: 5px 0">请求地址：<textarea style="display: inline-block;width: 100%;border: none;font-size: 14px;font-weight: bold;font-family: bold;">'
            . $this->httpUrl . request()->url() . '</textarea></h5>';
        is_array($data) && $data = json_encode($data);
        $html .= '<h5 style="margin: 5px 0">数据信息：<textarea style="display: inline-block;width: 100%;border: none;font-size: 14px;font-weight: bold;font-family: bold;">'
            . $data . '</textarea></h5>';
        $html .= '</div>';
        if (!file_exists($filename)) {
            $html .= '</body></html>';
        }
        file_put_contents($filename, $html, $flags);
    }

}